package cc.yugu.yhdw.webserver.service.hdw;

import cc.yugu.yhdw.common.constant.ConstEnum;
import cc.yugu.yhdw.common.domain.basic.Agent;
import cc.yugu.yhdw.common.domain.hdw.Agency;
import cc.yugu.yhdw.common.domain.hdw.ExchangeAmountMoneyDivideDetail;
import cc.yugu.yhdw.common.entity.json.ExtResult;
import cc.yugu.yhdw.common.entity.pagination.Page;
import cc.yugu.yhdw.common.entity.tree.Node;
import cc.yugu.yhdw.common.entity.tree.NodeModel;
import cc.yugu.yhdw.common.utils.YhdwUtils;
import cc.yugu.yhdw.webserver.persistence.basic.AgentMapper;
import cc.yugu.yhdw.webserver.persistence.basic.PassportMapper;
import cc.yugu.yhdw.webserver.persistence.basic.UserMapper;
import cc.yugu.yhdw.webserver.persistence.hdw.*;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
/**
 * 代理商业务
 *
 * @Date:Created in 2018/7/5 16:07
 * @Author:
 * @Modified By: zjn 2018/7/5 16:07
 */
@Service
public class AgencyService {
    @Autowired
    AgencyMapper agencyMapper;
    @Autowired
    AgentMapper agentMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    CabinetMapper cabinetMapper;
    @Autowired
    ExchangeAmountMoneyDivideDetailMapper exchangeAmountMoneyDivideDetailMapper;
    @Autowired
    ExchangeAmountMoneyDivideMapper exchangeAmountMoneyDivideMapper;
    @Autowired
    CabinetStrategyMapper cabinetStrategyMapper;
    @Autowired
    AgencyInOutMoneyMapper agencyInOutMoneyMapper;
    @Autowired
    PassportMapper passportMapper;
    /**
    * 查询代理商信息
    *
    * @Param: [id]
    * @Return: cc.yugu.yhdw.common.domain.hdw.Agency
    * @Author By: zjn 2018/7/5  16:07
    */
    public Agency find(Integer id) {
        // 根据主键id查询表hdw_agency
        Agency agency = agencyMapper.find(id);
        if (agency != null && agency.getAgentId() != null) {
            // 根据运营商id查询
            Agent agent = agentMapper.find(agency.getAgentId());
            agency.setAgentName(agent != null ? agent.getAgentName() : "无");
        }
        return agency;
    }
    /**
    * 查询
    *
    * @Param: [agentId]
    * @Return: java.util.List<cc.yugu.yhdw.common.domain.hdw.Agency>
    * @Author By: zjn 2018/7/5  16:08
    */
    public List<Agency> findByAgent(Integer agentId) {
        return agencyMapper.findByAgent(agentId, ConstEnum.Flag.TRUE.getValue());
    }
    /**
    * 分页查询
    *
    * @Param: [search]
    * @Return: cc.yugu.yhdw.common.entity.pagination.Page
    * @Author By: zjn 2018/7/5  16:09
    */
    public Page findPage(Agency search) {
        Page page = search.buildPage();
        page.setTotalItems(agencyMapper.findPageCount(search));
        search.setBeginIndex(page.getOffset());
        List<Agency> list = agencyMapper.findPageResult(search);
        for (Agency agency : list) {
            if (agency.getAgentId() != null && agency.getAgentId() != 0) {
                Agent agent = agentMapper.find(agency.getAgentId());
                agency.setAgentName(agent != null ? agent.getAgentName() : "");
            } else {
                agency.setAgentName("无");
            }
        }
        page.setResult(list);
        return page;
    }
    /**
    * 插入
    *
    * @Param: [agency]
    * @Return: cc.yugu.yhdw.common.entity.json.ExtResult
    * @Author By: zjn 2018/7/5  16:09
    */
    public ExtResult insert(Agency agency) {
        try {
            agency.setBalance(0);
            agency.setCreateTime(new Date());
            agencyMapper.insert(agency);
        } catch (Exception e) {
            return ExtResult.failResult("操作失败");
        }
        return ExtResult.successResult();
    }
    /**
    * 更新启用标识
    *
    * @Param: [id, activeFlag]
    * @Return: cc.yugu.yhdw.common.entity.json.ExtResult
    * @Author By: zjn 2018/7/5  16:10
    */
    public ExtResult disable(int id, int activeFlag) {
        try {
            // 按条件更新 启用标识
            agencyMapper.disable(id, null, activeFlag);
            userMapper.disable(id, null, null, activeFlag);
            cabinetMapper.disable(id, null, activeFlag);
        } catch (Exception e) {
            return ExtResult.failResult("操作失败");
        }
        return ExtResult.successResult();
    }
    /**
    * 删除
    *
    * @Param: [id]
    * @Return: cc.yugu.yhdw.common.entity.json.ExtResult
    * @Author By: zjn 2018/7/5  16:11
    */
    @Transactional(rollbackFor = Throwable.class)
    public ExtResult delete(int id) {
        try {
            agencyMapper.delete(id);
            agencyInOutMoneyMapper.deleteByAgency(id);
            passportMapper.updateAgency(id);
            userMapper.deleteByAgency(id);
            cabinetMapper.deleteByAgency(id);
            cabinetStrategyMapper.deleteByAgency(id);
            exchangeAmountMoneyDivideDetailMapper.deleteByAgency(id);
            exchangeAmountMoneyDivideMapper.deleteByAgency(id);
        } catch (Exception e) {
            return ExtResult.failResult("操作失败");
        }
        return ExtResult.successResult();
    }
    /**
    * 根据主键更新
    *
    * @Param: [entity]
    * @Return: cc.yugu.yhdw.common.entity.json.ExtResult
    * @Author By: zjn 2018/7/5  16:11
    */
    public ExtResult update(Agency entity) {
        try {
            agencyMapper.update(entity);
        } catch (Exception e) {
            return ExtResult.failResult("操作失败");
        }
        return ExtResult.successResult();
    }
    /**
    * 构建输出的目录树
    *
    * @Param: [dummy, agentId, parentId, showAgency, stream]
    * @Return: void
    * @Author By: zjn 2018/7/5  16:12
    */
    public void tree(String dummy, Integer agentId, Integer parentId, boolean showAgency, OutputStream stream) throws IOException {
        tree(buildTree(agentId, parentId, showAgency, dummy), stream);
    }

    private void tree(List<Node<NodeModel>> roots, OutputStream stream) throws IOException {

        ObjectMapper objectMapper = new ObjectMapper();
        JsonGenerator json = objectMapper.getJsonFactory().createJsonGenerator(stream, JsonEncoding.UTF8);
        json.writeStartArray();
        YhdwUtils.writeJson(roots, json);
        json.writeEndArray();

        json.flush();
        json.close();
    }
    /**
    * 构建目录树
    *
    * @Param: [agentId, parentId, showAgency, dummy]
    * @Return: java.util.List<cc.yugu.yhdw.common.entity.tree.Node<cc.yugu.yhdw.common.entity.tree.NodeModel>>
    * @Author By: zjn 2018/7/5  16:14
    */
    private List<Node<NodeModel>> buildTree(Integer agentId, Integer parentId, boolean showAgency, String dummy) {
        Set<Integer> checked = Collections.emptySet();

        List<Agency> agentList = agencyMapper.findByAgent(agentId, ConstEnum.Flag.TRUE.getValue());
        Map<Integer, Agency> allMap = new HashMap<Integer, Agency>();
        List<Agency> topList = new ArrayList<Agency>();

        for (Agency agent : agentList) {
            allMap.put(agent.getId(), agent);
            if (parentId == null) {
                if (agent.getParentId() == null) {
                    topList.add(agent);
                }
            } else {
                if (agent.getId().equals(parentId)) {
                    topList.add(agent);
                }
            }
        }

        List<Node<NodeModel>> roots = new ArrayList<Node<NodeModel>>();
        if (StringUtils.isNotEmpty(dummy)) {
            NodeModel data = new NodeModel();
            Node<NodeModel> root = new Node<NodeModel>(data);
            data.setId(0);
            data.setName(dummy);
            roots.add(root);

            for (Agency topAgency : topList) {
                NodeModel nodeModel = new NodeModel();
                Node<NodeModel> node = new Node<NodeModel>(nodeModel, root);

                nodeModel.setId(topAgency.getId());
                nodeModel.setName(topAgency.getAgencyName());
                nodeModel.setCheckStatus(checked.contains(topAgency.getId()) ? NodeModel.CheckedStatus.checked : NodeModel.CheckedStatus.unchecked);
                privateMakeTree(checked, node, showAgency, allMap, makeParentMap(allMap));
            }

        } else {
            for (Agency topAgency : topList) {
                NodeModel nodeModel = new NodeModel();
                Node<NodeModel> node = new Node<NodeModel>(nodeModel);

                nodeModel.setId(topAgency.getId());
                nodeModel.setName(topAgency.getAgencyName());
                nodeModel.setCheckStatus(checked.contains(topAgency.getId()) ? NodeModel.CheckedStatus.checked : NodeModel.CheckedStatus.unchecked);
                privateMakeTree(checked, node, showAgency, allMap, makeParentMap(allMap));
                roots.add(node);
            }
        }

        return roots;
    }
    /**
    * 往父节点添加子节点
    *
    * @Param: [checked, parent, showAgency, allMap, parentMap]
    * @Return: void
    * @Author By: zjn 2018/7/5  16:14
    */
    private void privateMakeTree(Set<Integer> checked, Node<NodeModel> parent, boolean showAgency, Map<Integer, Agency> allMap, Map<Integer, List<Integer>> parentMap) {
        List<Integer> sonIdList = parentMap.get(parent.getData().getId());
        if (sonIdList != null) {
            for (Integer id : sonIdList) {
                Agency agent = allMap.get(id);
                NodeModel nodeModel = new NodeModel();
                Node<NodeModel> node = new Node<NodeModel>(nodeModel);
                nodeModel.setId(agent.getId());
                nodeModel.setName(agent.getAgencyName());
                nodeModel.setCheckStatus(checked.contains(agent.getId()) ? NodeModel.CheckedStatus.checked : NodeModel.CheckedStatus.unchecked);
                parent.addChild(node);
                privateMakeTree(checked, node, showAgency, allMap, parentMap);
            }
        }
    }
    /**
    * 构建父节点
    *
    * @Param: [agentMap]
    * @Return: java.util.Map<java.lang.Integer,java.util.List<java.lang.Integer>>
    * @Author By: zjn 2018/7/5  16:15
    */
    private Map<Integer, List<Integer>> makeParentMap(Map<Integer, Agency> agentMap) {
        Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
        for (Map.Entry<Integer, Agency> entry : agentMap.entrySet()) {
            if (entry.getValue().getParentId() != null) {
                Integer parentId = entry.getValue().getParentId();
                List<Integer> v = map.get(parentId);
                if (v == null) {
                    map.put(parentId, v = new ArrayList<Integer>());
                }
                v.add(entry.getKey());
            }
        }

        return map;
    }
}
